package org.activemonitoring.config;

import org.activemonitoring.harvesters.HarvesterImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;

public class CreateBeanDefinitionParser extends AbstractBeanDefinitionParser {

    @Override
    protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
        BeanDefinitionRegistry registry = parserContext.getRegistry();
        boolean useDao = Boolean.parseBoolean(element.getAttribute("useDao"));
        boolean useJms = Boolean.parseBoolean(element.getAttribute("useJms"));
        boolean useRest = Boolean.parseBoolean(element.getAttribute("useRest"));
        if (useDao == false && useJms == false && useRest == false) {
            // Set useDao as the default option
            useDao = true;
        }
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(HarvesterImpl.class);
        if (useDao) {
            builder.addPropertyReference("dataStore", "dataStoreDao");
        } else if (useRest) {
            Element restElement = DomUtils.getChildElementByTagName(element, "rest");
            String datastoreUrl = restElement.getAttribute("datastoreUrl");
            builder.addPropertyReference("dataStore", "dataStoreRestClient");
            registry.getBeanDefinition("dataStoreRestClient").getPropertyValues().addPropertyValue("datastoreUrl",
                    datastoreUrl);
        } else if (useJms) {
            Element jmsElement = DomUtils.getChildElementByTagName(element, "jms");
            String jmsConnectionFactoryBeanName = jmsElement.getAttribute("connectionFactory");
            String jmsDestinationBeanName = jmsElement.getAttribute("destination");

            // Handle default values
            if (StringUtils.isEmpty(jmsConnectionFactoryBeanName)) {
                jmsConnectionFactoryBeanName = "jmsConnectionFactory";
            }
            if (StringUtils.isEmpty(jmsConnectionFactoryBeanName)) {
                jmsDestinationBeanName = "measureDestination";
            }

            builder.addPropertyReference("dataStore", "dataStoreJmsClient");
            BeanDefinition beanDefinition = registry.getBeanDefinition("jmsTemplate");
            MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
            propertyValues.addPropertyValue("defaultDestination", new RuntimeBeanReference(jmsDestinationBeanName));
            propertyValues
                    .addPropertyValue("connectionFactory", new RuntimeBeanReference(jmsConnectionFactoryBeanName));
        }
        return builder.getBeanDefinition();
    }
}
